/**
 * Created by jackliu on 16/1/14.
 * audio player &&  media player
 */
/**
 * 用法示例如下：
 var jsonObj =
 [{
                audio: [], // 数组(url,时长)
                video: [{
                        url: 'images/m/small.mp3',       // 音频地址
                        duration: 16,   // 时长,单位s

                        views:[
                          'images/m/small-step-0.jpg',
                          'images/m/small-step-1.jpg',
                        ],       // “视频拼图”数组
                        limit:25,       // 一个”视频拼图”的一行的”视频图”的张数
                        frame:25,       // 频率
                        step: 10,       // 一个”视频拼图”的时长,单位s
                        w:100,          // ”视频图”的宽度
                        h:178,          // ”视频图”的高度
                }]
              },{
                audio: [{
                        url: 'images/m/test.mp3',       // 音频地址
                        duration: 5,   // 时长,单位s
                }], // 数组(url,时长)
                video: []
              }]
 ;

 var player = new SJGMediaPlayer("can");
 player.init(jsonObj);
 player.cache(0,function(){});

 function play(){
      // 播放第0页
      player.play(0,0,function(){
        // 播放第1页
        player.play(1,0,function(){

        });
      });
    }
 function pause(){
      player.pause();
    }
 function goon(){
      player.play(0,1,function(){
        //  alert("播放完成");
      });
    }


 */

//-----------------------------公用函数--------------------------------------
var __extends = this.__extends || function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
        function __() { this.constructor = d; }
        __.prototype = b.prototype;
        d.prototype = new __();
    };


function $$(id){
    return document.getElementById(id);
}

var percent = 0;
function loadMsg(addPer){
    var lt = $$("load_txt");
    if (lt) {
        percent = percent + Number(addPer);
        if (percent>100) {
            percent = 100;
        }
        lt.innerHTML="媒体加载中..."+"<br>("+percent+"/100)";
    }
}
var RET_OK = 0;
var RET_ERROR = 1;
//-----------------------------SJGAudio--------------------------------------
// audio
// {
//      url: xxx,       // 音频地址
//      duration: 25,   // 时长,单位s
//
//      audioCache:     // [@@@@@@内部使用]视频缓存 Audio类型
// }
var SJGAudio = (function(){
    function SJGAudio(jsonObj){
        if(jsonObj){
            this.url=jsonObj.url;
            this.duration=jsonObj.duration;
            this.audioCache = null;             // 缓存
        }else{
            this.url=null;
            this.duration=0;
            this.audioCache = null;             // 缓存
        }
    }
    // public:
    // 是否存在音频
    SJGAudio.prototype.isEmpty = function () {
        return this.url==null;
    }
    // public:
    // 缓存结束
    SJGAudio.prototype.isCacheEnd = function(){
        return this.audioCache!=null;
    }
    // public:
    // 开启缓存
    SJGAudio.prototype.cache = function(callback){

        var THIS = this;
        if(this.isCacheEnd()){
            callback(RET_OK);
            return;
        }
        var sound = new Audio();
        /*
         * There are 7 events that fire in this order when an audio file is loaded:
         loadstart
         durationchange
         loadedmetadata
         loadeddata
         progress
         canplay
         canplaythrough
         * */
        function eventLoaded() {
            // 删除监听
            sound.removeEventListener('canplaythrough', eventLoaded);
            //  缓存
            THIS.audioCache = sound;

            loadMsg(10)
            // 回调
            callback(RET_OK);
        }
        function eventLoadedErr() {
            // 删除监听
            sound.removeEventListener('error', eventLoadedErr);
            // 回调
            callback(RET_ERROR);
        }
        // 重新添加监听
        sound.removeEventListener('canplaythrough', eventLoaded);
        sound.removeEventListener('error', eventLoadedErr);
        sound.addEventListener('canplaythrough', eventLoaded, false);
        sound.addEventListener('error', eventLoadedErr, false);
        //选择文件
        sound.src = this.url;
        sound.load();
    }

    SJGAudio.prototype.playEnd = function(){
        var audioScope = this;
        audioScope.THIS.audioCache.removeEventListener('ended', audioScope.THIS.playEnd);
        audioScope.THIS.clearUI();
        audioScope.callback();
    }
    // public:
    // 播放
    // 参数：flag，0表示重新放，1表示继续
    // 参数：callback，完成播放后的回调
    // 注意：在播放之前需要开启缓存
    SJGAudio.prototype.play = function(flag, callback){
        var THIS = this;

        if(this.audioCache){
            this.audioCache.THIS = THIS;
            this.audioCache.callback = callback;

            this.audioCache.removeEventListener('ended', this.playEnd);
            this.audioCache.addEventListener('ended', this.playEnd);

            if(flag==0){// 重新播放
                this.audioCache.currentTime=0;
            }

            this.audioCache.play();
        }else{
            callback();
        }
    }
    // public:
    // 清除界面
    SJGAudio.prototype.clearUI = function(){

    }
    // public:
    // 暂停
    SJGAudio.prototype.pause = function(){
        if(this.audioCache){
            this.audioCache.pause();
        }
    }

    return SJGAudio;
})();
//-----------------------------SJGVideo--------------------------------------
// media
//  {
//      url: xxx,       // 音频地址
//      duration: 25,   // 时长,单位s
//      views:[],       // “视频拼图”数组
//      limit:40,       // 一个”视频拼图”的一行的”视频图”的张数
//      frame:25,       // 频率
//      step: 10,       // 一个”视频拼图”的时长,单位s
//      w:200,          // ”视频图”的宽度
//      h:300,          // ”视频图”的高度

//
//      viewsCache:[],  // [@@@@@@内部使用]视频缓存 Image类型
//      context,        // [@@@@@@内部使用]视频canvas的context
//      interval,       // [@@@@@@内部使用]定时器时长,单位ms
//      currentTime,    // [@@@@@@内部使用]当前播放时间,单位ms
// }
var SJGVideo = (function(_super){
    __extends(SJGVideo, _super);
    function SJGVideo(jsonObj, context, canvas){
        _super.call(this, jsonObj);
        if(jsonObj, context, canvas){
            this.views=jsonObj.views;
            this.limit=jsonObj.limit;
            this.frame = jsonObj.frame;
            this.step = jsonObj.step;
            this.w = jsonObj.w;
            this.h = jsonObj.h;

            this.canvas = canvas;
            this.context = context;
            this.videoCache = new Array(this.views.length);             // 缓存
            this.interval = 1000/this.frame;
            this.currentTime=0;
        }else{
            this.views=[];
            this.limit=40;
            this.frame = 25;
            this.step = 10;
            this.w = 200;
            this.h = 300;

            this.canvas = null;
            this.context = null;
            this.videoCache = [];             // 缓存
            this.interval = 1000/this.frame;
            this.currentTime=0;
        }
    }
    // public:
    // 是否存在音视频
    SJGVideo.prototype.isEmpty = function () {
        return _super.prototype.isEmpty.call(this) && this.isViewsEmpty();
    }
    // public:
    // 缓存结束
    SJGVideo.prototype.isCacheEnd = function(){
        if(! _super.prototype.isCacheEnd.call(this) ){
            return false;
        }
        if(! this.isCacheViewsEnd()){
            return false;
        }
        return true;
    }
    // public:
    // 开启缓存
    SJGVideo.prototype.cache = function(callback){
        var THIS=this;
        // 缓存音频
        _super.prototype.cache.call(this,function(ret){
            if (ret == RET_ERROR){
                callback(RET_ERROR)
            } else {
                // 音频和视频缓存完成后，回调
                if(THIS.isCacheEnd()){
                    callback(RET_OK)
                }
            }
        });
        // 缓存视频
        this.cacheViews(function(){
            // 音频和视频缓存完成后，回调
            if(THIS.isCacheEnd()){
                callback(RET_OK)
            }
        });
    }

    // public:
    // 播放
    // 参数：flag，0表示重新放，1表示继续
    // 参数：callback，完成播放后的回调
    // 注意：在播放之前需要开启缓存
    SJGVideo.prototype.play = function(flag, callback){
        // 音频
        _super.prototype.play.call(this, flag, callback);

        // 视频
        if(this.audioCache){
            this.playViews(this.audioCache.currentTime);
        }
    }
    // public:
    // 清除界面
    SJGVideo.prototype.clearUI = function(){
        _super.prototype.clearUI.call(this);

        this.context.clearRect(0,0, this.w, this.h);
    }
    // public:
    // 暂停
    SJGVideo.prototype.pause = function(){
        // 音频
        _super.prototype.pause.call(this);

        // 视频－关闭定时器
        this.clearTimer();
    }
    // 清除定时器
    SJGVideo.prototype.clearTimer = function(){
        // 定时器
        if(this.timerID){
            clearInterval(this.timerID);
            this.timerID = null;
        }
    }
    // 播放视频
    // 参数：currentTime，从第几秒开始播放
    SJGVideo.prototype.playViews = function (currentTime) {
        var THIS = this;
        // 当前播放时间
        this.currentTime = currentTime*1000;
        // 定时器
        this.clearTimer();
        this.clearUI();
        $(".video").addClass("display_hide");// 隐藏canvas

        this.timerID= setInterval(function(){
            if ($(".video").hasClass("display_hide")){
                $(".video").removeClass("display_hide");// 显示canvas
            }

            THIS.playViewsCore.call(THIS);
        }, this.interval);
    }
    // 播放视频core
    // 参数：time，从第几秒开始播放
    SJGVideo.prototype.playViewsCore = function () {
        // 如果播放时间到了，则清除定时器
        if(this.currentTime >= 1000*this.duration){
            $(".video").addClass("display_hide");// 隐藏canvas
            this.clearTimer();// 清除定时器
            this.clearUI();
            return;
        }
        // ”视频拼图”的index
        var index = parseInt(this.currentTime/(this.step*1000));
        if (index >= this.videoCache.length){// index保护
            $(".video").addClass("display_hide");// 隐藏canvas
            this.clearTimer();
            this.clearUI();
            return;
        }
        var img = this.videoCache[index];

        // "视频图"的index
        var num = parseInt((this.currentTime-index*this.step*1000)/(this.interval));
        var row = parseInt(num/this.limit);
        var col = num%this.limit;

        //console.log("--->currentTime:"+this.currentTime+",index:"+index+",row:"+row+",col:"+col);



        // 描绘
        //this.context.drawImage(img, col*this.w, row*this.h, this.w, this.h, 0, 0,this.w,this.h);

        this.canvas.width = this.canvas.width;// clear the canvas by reset w/h!

        if (gIsPortrait) {
            // 等比缩放图片撑满canvas不留白
            var scaleW = this.canvas.height/this.w;
            var scaleH = this.canvas.width/this.h;
            var s = (scaleW>scaleH)?scaleW:scaleH;
            var x = -(this.w*s-this.canvas.height)/2;
            var y = -(this.h*s-this.canvas.width)/2;

            this.context.rotate(Math.PI / 2);
            this.context.drawImage(img, col*this.w, row*this.h, this.w, this.h,
                x, y-this.canvas.width, this.w*s, this.h*s);

        } else {
            // 等比缩放图片撑满canvas不留白
            var scaleW = this.canvas.width/this.w;
            var scaleH = this.canvas.height/this.h;
            var s = (scaleW>scaleH)?scaleW:scaleH;
            var x = -(this.w*s-this.canvas.width)/2;
            var y = -(this.h*s-this.canvas.height)/2;

            this.context.drawImage(img, col*this.w, row*this.h, this.w, this.h,
                x, y, this.w*s, this.h*s);
        }

        // 累加时间
        this.currentTime += this.interval;
    }

    // 是否存在视频
    SJGVideo.prototype.isViewsEmpty = function () {
        if(!this.views || this.views.length==0){
            return true;
        }
        for(var i=0;i<this.views.length;i++){
            if(this.views[i]){
                return false;
            }
        }
        return true;
    }

    // 缓存视频结束
    SJGVideo.prototype.isCacheViewsEnd = function(){
        if(this.videoCache.length!= this.views.length){
            return false;
        }
        for(var i=0;i<this.videoCache.length;i++){
            if(!this.videoCache[i]){
                return false;
            }
        }
        return true;
    }
    // 开启缓存views
    SJGVideo.prototype.cacheViews = function(callback){
        var THIS = this;
        for(var i=0;i<this.views.length;i++){
            (function(index, view){
                var imgmain = new Image();
                imgmain.addEventListener('load', function eventLoaded() {
                    loadMsg(15);
                    THIS.videoCache[index] = imgmain;
                    // 所有视频缓存完成后才回调
                    if(THIS.isCacheViewsEnd()){
                        callback()
                    }
                }, false);
                imgmain.src = view;
            })(i, this.views[i]);
        }
    }

    return SJGVideo;
})(SJGAudio);

//-----------------------------SJGMediaPage--------------------------------------
// SJGMediaPage
// {
//      items:[] , // SJGAudio或者SJGVideo
// }
var SJGMediaPage = (function() {
    function SJGMediaPage() {
        this.items = [];
    }

    // public:
    // 是否存在音视频
    SJGMediaPage.prototype.isEmpty = function () {
        if(this.items.length==0){
            return true;
        }
        for (var i = 0; i < this.items.length; i++) {
            if (!this.items[i].isEmpty()) {
                return false;
            }
        }
        return true;
    }


    // public:
    // 缓存结束
    SJGMediaPage.prototype.isCacheEnd = function(){
        for(var i=0;i<this.items.length;i++){
            if(!this.items[i].isCacheEnd()){
                return false;
            }
        }
        return true;
    }
    // public:
    // 开启缓存页上的音视频
    SJGMediaPage.prototype.cache = function( callback){
        var THIS=this;
        // 所有页上的音视频完成缓存后发起回调
        if(this.isCacheEnd()){
            callback(RET_OK);
            return;
        }

        for(var i=0;i<this.items.length;i++){
            (function(index, item){
                item.cache(function(ret){
                    if (ret == RET_ERROR){
                        callback(RET_ERROR);
                    } else {
                        // 所有页上的音视频完成缓存后发起回调
                        if(THIS.isCacheEnd()){
                            callback(RET_OK);
                        }
                    }
                });
            })(i,this.items[i]);
        }
    }
    // public:
    // 播放
    // 参数：flag，0表示重新放，1表示继续
    // 参数：callback，完成播放后的回调
    // 注意：在播放之前需要开启缓存
    SJGMediaPage.prototype.play = function(flag, callback){
        var THIS=this;
        // 目前只有至多一个元素
        var item = this.items[0];
        if(item){
            item.play(flag, callback);
        }else{
            callback()
        }
    }
    // public:
    // 暂停
    SJGMediaPage.prototype.pause = function(){
        // 目前只有至多一个元素
        var item = this.items[0];
        if(item){
            item.pause();
        }
    }

    return SJGMediaPage;
})();

//-----------------------------SJGMediaPlayer--------------------------------------
// media player
var SJGMediaPlayer = (function () {
    function SJGMediaPlayer(canvasId) {
        this.pages = [] ;// 当前页

        this.current=0;// 当前页index

        this.canvas = $$(canvasId);
        this.context = $$(canvasId).getContext('2d'); // 描绘视频的画布
    }
    // public:
    // 初始页面数据
    // 参数：jsonObj:结构如下：
    //      [{
    //          audio: [], // audio 数组，元素为 SJGAudio 类型
    //          video: [] // video 数组，元素为 SJGVideo 类型
    //      }]
    // 返回: 如有视频返回{w:20,h:30},否则返回空
    SJGMediaPlayer.prototype.init = function (jsonObj) {
        if(!jsonObj)    return;

        var wh = null;
        for(var i=0;i<jsonObj.length;i++){
            var one = jsonObj[i];
            if(one){
                if(one.audio && one.audio.length>0){
                    var page = new SJGMediaPage();
                    for(var j=0;j<one.audio.length;j++){
                        var audio = new SJGAudio(one.audio[j]);
                        page.items.push(audio);
                    }
                    this.pages.push(page);
                }else if(one.video && one.video.length>0){
                    var page = new SJGMediaPage();
                    for(var j=0;j<one.video.length;j++){
                        var video = new SJGVideo(one.video[j],this.context,this.canvas);
                        page.items.push(video);
                        if (wh == null && video.w>0 && video.h>0) {
                            wh = {w:video.w, h:video.h};
                        }
                    }
                    this.pages.push(page);
                }else{
                    this.pages.push(null);
                }
            }
        }

        return wh;
    };
    // public:
    // 开启缓存(目标页如果没有媒体，则往后找有媒体的页面并缓存)
    // 参数：index，页index
    // 参数：callback，完成该页缓存后的回调
    // 返回值：0表示index页没有媒体无播放，1表示index页有媒体有播放（缓存完成后会回调callback）
    SJGMediaPlayer.prototype.cache = function(index, callback){
        var THIS=this;

        // 开启缓存
        //var page = this.pages[index];

        var ret = 0;
        for (var i=index; i<this.pages.length; i++){
            var page = this.pages[i];
            if (page && !page.isEmpty()){
                if (i == index) {
                    ret = 1;
                }
                // 本页有媒体
                loadMsg(5);
                page.cache(function(ret){
                    loadMsg(100);
                    callback(ret)
                });
                break;
            }
        }

        return ret;
    }

    // public:
    // 播放
    // 参数：index，页index
    // 参数：flag，0表示重新放，1表示继续
    // 参数：callback，完成播放后的回调
    // 返回值：0表示没有媒体无播放，1表示有媒体有播放（播放完成后会回调callback）
    // 注意：在播放之前需要开启缓存
    SJGMediaPlayer.prototype.play = function(index,flag, callback){
        var THIS=this;
        var page = this.pages[index];
        if(!page || page.isEmpty()){
            return 0 ;
        }

        this.current = index; // 记录当前页下标

        // 缓存后再播放
        this.cache(index, function(ret){
            if (ret == RET_ERROR) {
                callback(RET_ERROR);
                return;
            }
            page.play(flag, function(){
                callback(RET_OK);
            });
            // 自动缓存下一页
            THIS.cache(index+1, function(){});
        });

        return 1;
    }

    // public:
    // 暂停
    SJGMediaPlayer.prototype.pause = function(){
        var page = this.pages[this.current];
        if(!page || page.isEmpty()){
            return ;
        }

        page.pause();
    }

    return SJGMediaPlayer;
})();